package com.tomecode.tools.maven.settings.gui.tray;

import java.awt.AWTException;
import java.awt.CheckboxMenuItem;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;

import com.tomecode.tools.maven.settings.SettingsFactory;
import com.tomecode.tools.maven.settings.gui.Desktop;
import com.tomecode.tools.maven.settings.gui.FrmBackupList;
import com.tomecode.tools.maven.settings.gui.FrmError;
import com.tomecode.tools.maven.settings.gui.FrmSettingsXmlPath;
import com.tomecode.tools.maven.settings.gui.images.ImageFactory;
import com.tomecode.tools.maven.settings.model.Profile;
import com.tomecode.tools.maven.settings.model.Settings;
import com.tomecode.util.gui.HideNotifiListener;

/**
 * System tray icon
 * 
 * 
 * @author Frastia Tomas
 * 
 */
public final class Tray {

	private static final Tray me = new Tray();

	private final TrayIcon trayIcon;

	private final PopupMenu popupMenu;

	private Settings settings;

	private Tray() {
		popupMenu = new PopupMenu();

		trayIcon = new TrayIcon(Toolkit.getDefaultToolkit().getImage(ImageFactory.getApp()), "Maven Settings Editor");
		trayIcon.setImageAutoSize(true);
		loadSettings();
		try {
			SystemTray.getSystemTray().add(trayIcon);
		} catch (AWTException e) {
			e.printStackTrace();
		}
	}

	private final void loadSettings() {
		try {
			settings = SettingsFactory.loadSettings();
			trayIcon.setPopupMenu(getMenu());
			// } catch (DocumentException e) {
			// FrmError.showMe("Failed load maven settings.xml - wrong document",
			// e);
			// } catch (FileNotFoundException e) {
			// trayIcon.setCaption("not found maven settings file");
			// trayIcon.setPopupMenu(getMenuOnlySetMavenFile());
			// } catch (IOException e) {
			// FrmError.showMe("Failed load maven settings.xml", e);
			// }
		} catch (Exception e) {
			trayIcon.setToolTip("not found maven settings file");
			// trayIcon.setCaption("not found maven settings file");
			trayIcon.setPopupMenu(getMenuOnlySetMavenFile());
		}
	}

	/**
	 * create {@link JMenu} only for set maven settings.xml
	 * 
	 * @return
	 */
	private final PopupMenu getMenuOnlySetMavenFile() {
		PopupMenu menu = new PopupMenu();

		menu.add(createMenuItem("Maven settings.xml file", new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				FrmSettingsXmlPath.showMe("Not found Maven settings sxml", new HideNotifiListener() {
					public final void hideForm(Object loadSettings) {
						settings = (Settings) loadSettings;
						if (settings != null) {
							trayIcon.setPopupMenu(getMenu());
						} else {
							trayIcon.setPopupMenu(getMenuOnlySetMavenFile());
						}
					}
				});
			}
		}));

		menu.addSeparator();
		menu.add(getMenuItemQuit());
		return menu;
	}

	/**
	 * create default {@link JPopupMenu}
	 * 
	 * @return
	 */
	private final PopupMenu getMenu() {
		popupMenu.removeAll();

		popupMenu.add(createCheckBoxMenuItem("Interactive mode", settings.isInteractiveMode(), new ActionListener() {
			public final void actionPerformed(ActionEvent e) {

				if (((JCheckBoxMenuItem) e.getSource()).isSelected()) {
					settings.setInteractiveMode(true);
					settings.removeCommented(SettingsFactory.E_INTERACTIVE_MODE);
					settings.removeDeleted(SettingsFactory.E_INTERACTIVE_MODE);
				} else {
					settings.setInteractiveMode(false);
					settings.setDeleted(SettingsFactory.E_INTERACTIVE_MODE);
					settings.setCommented(SettingsFactory.E_INTERACTIVE_MODE);
				}

				saveChanges();
			}
		}));
		popupMenu.add(createCheckBoxMenuItem("Use Plugin Registry", settings.isUsePluginRegistry(), new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				if (((JCheckBoxMenuItem) e.getSource()).isSelected()) {
					settings.setUsePluginRegistry(true);
					settings.removeCommented(SettingsFactory.E_USE_PLUGIN_REGISTRY);
					settings.removeDeleted(SettingsFactory.E_USE_PLUGIN_REGISTRY);
				} else {
					settings.setUsePluginRegistry(false);
					settings.setCommented(SettingsFactory.E_USE_PLUGIN_REGISTRY);
					settings.setDeleted(SettingsFactory.E_USE_PLUGIN_REGISTRY);
				}
				saveChanges();
			}
		}));
		popupMenu.add(createCheckBoxMenuItem("Offline", settings.isOffline(), new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				if (((JCheckBoxMenuItem) e.getSource()).isSelected()) {
					settings.setOffline(true);
					settings.removeCommented(SettingsFactory.E_OFFLINE);
					settings.removeDeleted(SettingsFactory.E_OFFLINE);
				} else {
					settings.setOffline(false);
					settings.setCommented(SettingsFactory.E_OFFLINE);
					settings.setDeleted(SettingsFactory.E_OFFLINE);
				}
				saveChanges();
			}
		}));
		popupMenu.addSeparator();
		popupMenu.add(createActiveProfiles());
		popupMenu.add(createMenuItem("Reload settings.xml", new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				loadSettings();
			}
		}));
		popupMenu.add(createMenuItem("Show Editor", new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				showEditor();
			}
		}));
		popupMenu.addSeparator();
		popupMenu.add(createBackup());
		popupMenu.addSeparator();
		popupMenu.add(getMenuItemQuit());

		return popupMenu;
	}

	/**
	 * create backup menu
	 * 
	 * @return
	 */
	private final Menu createBackup() {
		Menu menu = new Menu("Backup");

		menu.add(createMenuItem("Create Backup from current version", new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				try {
					JOptionPane.showMessageDialog(null, "Sucessfull create backup settings.xml:\n" + SettingsFactory.backup(settings).getPath(), "Create Backup", JOptionPane.INFORMATION_MESSAGE);
				} catch (IOException ex) {
					FrmError.showMe("Failed creatae backup", ex);
				}
			}
		}));
		menu.add(createMenuItem("Restore from backups", new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				block();
				FrmBackupList.showMe(settings.getFile(), SettingsFactory.loadBackups(settings.getFile().getParentFile()));
			}
		}));
		return menu;
	}

	/**
	 * crate active profile
	 * 
	 * @return
	 */
	private final MenuItem createActiveProfiles() {
		Menu menu = new Menu("Active profiles");

		for (Profile profile : settings.getProfiles()) {
			CheckboxMenuItem checkBoxMenuItem = createCheckBoxMenuItem(profile.getId());
			if (settings.isActiveProfile(profile.getId())) {
				checkBoxMenuItem.setState(true);
			}

			menu.add(checkBoxMenuItem);
		}

		return menu;
	}

	/**
	 * create quit {@link JMenuItem}
	 * 
	 * @return
	 */
	private final MenuItem getMenuItemQuit() {
		return createMenuItem("Quit", new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				System.exit(0);
			}
		});
	}

	private final CheckboxMenuItem createCheckBoxMenuItem(String name, boolean state, ActionListener actionListener) {
		CheckboxMenuItem checkBoxMenuItem = new CheckboxMenuItem(name, state);
		checkBoxMenuItem.setActionCommand(name);
		checkBoxMenuItem.addActionListener(actionListener);
		return checkBoxMenuItem;
	}

	/**
	 * create {@link JCheckBoxMenuItem}
	 * 
	 * @param name
	 * @return
	 */
	private final CheckboxMenuItem createCheckBoxMenuItem(String name) {
		CheckboxMenuItem checkBoxMenuItem = new CheckboxMenuItem(name);
		checkBoxMenuItem.setActionCommand(name);
		checkBoxMenuItem.addActionListener(new ActionListener() {
			public final void actionPerformed(ActionEvent e) {
				JCheckBoxMenuItem check = (JCheckBoxMenuItem) e.getSource();
				if (check.isSelected()) {
					settings.addActiveProfile(e.getActionCommand());
				} else {
					settings.removeActiveProfile(e.getActionCommand());
				}
				saveChanges();
			}
		});
		return checkBoxMenuItem;
	}

	private final void saveChanges() {
		try {
			SettingsFactory.save(settings);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	/**
	 * create new {@link JMenuItem} and add {@link ActionListener}
	 * 
	 * @param name
	 * @param actionListener
	 * @return
	 */
	private final MenuItem createMenuItem(String name, ActionListener actionListener) {
		MenuItem menuItem = new MenuItem(name);
		menuItem.setName(name);
		menuItem.addActionListener(actionListener);
		return menuItem;
	}

	/**
	 * show editor
	 */
	private final void showEditor() {
		block();
		Desktop.showMe(settings);
	}

	/**
	 * instance of {@link Tray}
	 * 
	 * @return
	 */
	public static final Tray getInstance() {
		return me;
	}

	/**
	 * reload settings
	 */
	public final void reload() {
		loadSettings();
		trayIcon.setPopupMenu(getMenu());
	}

	/**
	 * block all menu item;
	 */
	public final void block() {
		setEnableForMenu(false);
	}

	private final void setEnableForMenu(boolean b) {
		for (int i = 0; i <= popupMenu.getItemCount() - 1; i++) {
			if (popupMenu.getItem(i).getLabel() != null && popupMenu.getItem(i).getLabel().equals("Quit")) {
				continue;
			}
			popupMenu.getItem(i).setEnabled(b);
		}
		// for (Component component : popupMenu.g) {
		// if (component.getName() != null &&
		// component.getName().equals("Quit")) {
		// continue;
		// }
		// component.setEnabled(b);
		// }
	}

	/**
	 * unblock all menu item
	 */
	public final void unblock() {
		setEnableForMenu(true);
	}
}
